### Декораторы Python

это мощные инструменты, которые помогают вам создавать чистый, многоразовый и поддерживаемый код.

Декораторы ничем не отличаются от обычных функций, вы просто вызываете их более причудливым способом.

### Встроенные декораторы

`@lru_cache` 

Он кэширует возвращаемые значения функции, используя алгоритмы кэширования (LRU) для удаления наименее используемых значений, когда кэш заполнен.

`@dataclass`
Декоратор @dataclass в Python используется для оформления классов.

Он автоматически генерирует специальные методы, такие как `__init__, __repr__, __eq__, __lt__ и __str__` для классов, которые хранят данные. 

Это может сократить объём шаблонного кода и сделать классы более удобочитаемыми и ремонтопригодными.

Он также предоставляет готовые методы для красивого представления объектов, преобразования их в формат JSON, придания им неизменяемости и т.д.

```python
from dataclasses import dataclass, 

@dataclass
class Person:
    first_name: str
    last_name: str
    age: int
    job: str

anne = Person(first_name="Anne", 
              last_name="Smith", 
              age=40, 
              job="software engineer",)

```

 `@singledispatch`
Этот декоратор позволяет функции иметь разные реализации для разных типов аргументов (полиформизм).

```python
from functools import singledispatch

@singledispatch
def fun(arg):
    print("1 аргумент:", arg)

@fun.register(int)
def _(arg):
    print("Вызов числом")

@fun.register(list)
def _(arg):
    print("Вызов списком")

fun('привет')
fun(1)
fun([1, 2, 3])

```

### Несколько декораторов

```python
def h1(func):
    def wrapper():
        return '<h1>\n' + func() + '\n</h1>'
    return wrapper

def div(func):
    def wrapper():
        return '\t<p> ' + func() + ' </p>'
    return wrapper

@h1
@p
def hello():
    return 'Привет'


print (hello())
```


Результат
```html
<h1>
	<p> Привет </p>
</h1>
```

Передача параметра в декоратор
```python
def h1(func):
    def wrapper(title):
        return '<h1>\n' + func(title) + '\n</h1>'
    return wrapper

@h1
@div
def hello(title):
    return title

print (hello('Привет'))

```